package com.hevs.samplewebapp.client.dialogbox;

import javax.validation.ValidationException;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.datepicker.client.DateBox;
import com.hevs.samplewebapp.client.bean.Category;
import com.hevs.samplewebapp.client.bean.FieldVerifier;
import com.hevs.samplewebapp.client.bean.MedicalDataItem;
import com.hevs.samplewebapp.client.bean.Type;
import com.hevs.samplewebapp.client.screens.ManageMedicalDataWidget;

/**
 * Dialog box for modification
 * <p>It provides a dialog box to modifie a data</p>
 * @author Lionel Rey, Schnidrig Peter
 * @date 02.04.2012
 *
 */
public class ModifyDialogBox extends DialogBox{

	// ------------------------------------------------------------
	// VARIABLES
	// ------------------------------------------------------------
	
	/**
	 * Boolean for the OK
	 */
	public static final boolean OK = true;
	
	/**
	 * Boolean for the CANCEL
	 */
	public static final boolean CANCEL = false;
	
	/**
	 * Default boolean choice
	 */
	private boolean choice = CANCEL;

	/**
	 * Flextable to layout the GUI elements
	 */
	private FlexTable tableLayout=new FlexTable();

	/**
	 * Vertical panel is the main panel of the dialog box
	 */
	private VerticalPanel mainLayout = new VerticalPanel();
	
	/**
	 * Horizontal panel for the buttons
	 */
	private HorizontalPanel buttonsLayout = new HorizontalPanel();

	/**
	 * Textbox with the value of the medical data
	 */
	private TextBox tbValue = new TextBox();
	
	/**
	 * Listbox with the category of the medicaldata
	 */
	private ListBox tbCategory = new ListBox();
	
	/**
	 * Listbox with the type of the medical data
	 */
	private ListBox tbType = new ListBox();
	
	/**
	 * Datebox with the date of the medical data
	 */
	private DateBox tbDate = new DateBox();

	/**
	 * widget with the medical data
	 * @see ManageMedicalDataWidget
	 */
	private ManageMedicalDataWidget medicalDataWidget = new ManageMedicalDataWidget();

	/**
	 * Formater for the date
	 */
	private DateTimeFormat dateFormat=DateTimeFormat.getFormat("dd.MM.yyyy");
	
	/**
	 * The medical data that will be updated
	 */
	private MedicalDataItem medicalDataItem;

	// ------------------------------------------------------------
	// CONSTRUCTORS
	// ------------------------------------------------------------
	/**
	 * Constructor of the dialog box
	 * @param medicalDataItem
	 * the medical data that will be updated
	 */
	public ModifyDialogBox(MedicalDataItem medicalDataItem){
		super(false,false);
		initDialogBox(medicalDataItem);
	}

	/**
	 * Getter of the choice to update or cancel
	 * @return
	 * the choice in boolean format
	 */
	public boolean getChoice(){
		return choice;
	}

	/**
	 * Method to initialize the dialog box
	 * @param medicalDataItem
	 * the medical data that will be updated
	 */
	private void initDialogBox(final MedicalDataItem medicalDataItem) {
		this.setText("Modification");
		this.setGlassEnabled(true);
		this.setAnimationEnabled(true);

		// Fill the ListBoxes with defined Types and Categories
		for(int i=0;i<Category.getSize();i++)
		{
			Category temp=Category.get(i);
			tbCategory.addItem(temp.getName(),String.valueOf(temp.getLevel()));
		}
		for(int i=0;i<Type.getSize();i++)
		{
			Type temp=Type.getFromInt(i);
			tbType.addItem(temp.getName(),String.valueOf(temp.getLevel()));
		}

		tbType.setSelectedIndex(Type.getIndex(medicalDataItem.getType()));
		tbValue.setText(medicalDataItem.getValue()+"");
		tbCategory.setSelectedIndex(medicalDataItem.getCategory());
		tbDate.setFormat(new DateBox.DefaultFormat(dateFormat));
		tbDate.setValue(dateFormat.parse(medicalDataItem.getDate()),true);
		tbDate.getDatePicker().setCurrentMonth(tbDate.getValue());

		tableLayout.setHTML(1,0,"Value:");
		tableLayout.setWidget(1,1,tbValue);
		tableLayout.setHTML(2,0,"Date:");
		tableLayout.setWidget(2,1,tbDate);
		tableLayout.setHTML(3,0,"Category:");
		tableLayout.setWidget(3,1,tbCategory);
		tableLayout.setHTML(4,0,"Type:");
		tableLayout.setWidget(4,1,tbType);

		Button btnOK = new Button("Update");
		Button btnCancel = new Button("Cancel");
		btnOK.setWidth("100%");
		btnCancel.setWidth("100%");
		buttonsLayout.add(btnOK);
		buttonsLayout.add(btnCancel);
		buttonsLayout.setSpacing(10);

		mainLayout.add(tableLayout);
		mainLayout.add(buttonsLayout);
		mainLayout.setSpacing(5);
		mainLayout.setCellHorizontalAlignment(buttonsLayout,VerticalPanel.ALIGN_CENTER);

		this.setWidget(mainLayout);

		btnOK.addClickHandler(new ClickHandler() {              
			@Override
			public void onClick(ClickEvent event) {
				try{
					checkValue(tbType.getSelectedIndex());
					medicalDataItem.setCategory(tbCategory.getSelectedIndex());
					medicalDataItem.setDate(dateFormat.format(tbDate.getValue()));
					medicalDataItem.setType(Integer.parseInt(tbType.getValue(tbType.getSelectedIndex())));
					medicalDataItem.setValue(Double.parseDouble(tbValue.getText()));
					//ask for updating, if yes update medicalData;
					medicalDataWidget.askingUpdate(medicalDataItem);

					choice  = ModifyDialogBox.OK;
					ModifyDialogBox.this.hide();
				}catch (ValidationException e) {

				}
			}
		});

		btnCancel.addClickHandler(new ClickHandler() {  
			@Override
			public void onClick(ClickEvent event) {
				choice  = ModifyDialogBox.CANCEL;
				ModifyDialogBox.this.hide();
			}
		});

		this.show();
		this.center();
	}

	/**
	 * Method to return the updated version of the data
	 * @return
	 * updated object medical data
	 */
	public MedicalDataItem updatedData() {
		return medicalDataItem ;
	}


	/**
	 * Method to check the validation of the update
	 * @param type
	 * the type of the medical data in int format
	 */
	private void checkValue(int type)
	{
		Type temp=Type.getFromInt(type);
		switch (temp)
		{
		case BLOODSUGAR:
			FieldVerifier.validateCategory("Blood sugar",tbValue,tbCategory);
			FieldVerifier.validateAndParseDouble("Blood sugar", tbValue, 0., 200.);
			break;
		case HUMALOG: case NOVORAPID:
			FieldVerifier.validateCategory("Quantity of insuline",tbValue,tbCategory);
			FieldVerifier.validateAndParseInt("Quantity of insuline", tbValue, 0, 100);
			break;
		case WEIGHT:
			FieldVerifier.validateAndParseDouble("Weight", tbValue, 0., 400.);
			break;
		case DIASTOLIC:
			FieldVerifier.validateAndParseDouble("Diastolic Blood Presure", tbValue, 0., 300.);
			break;
		case SYSTOLIC:
			FieldVerifier.validateAndParseDouble("Systolic Blood Presure", tbValue, 0., 300.);
			break;
		case PULSERATE:
			FieldVerifier.validateAndParseInt("Pulse rate", tbValue, 1, 300);
			break;
		default:
			throw new ValidationException("Not a valid type!");
		}
	}
}